<template>
  <div class="log-monitor">
    <el-card shadow="never">
      <div slot="header" class="card-header">
        <span>系统日志监控</span>
        <div class="header-buttons">
          <el-button-group>
            <el-button 
              :type="isMonitoring ? 'success' : 'primary'" 
              :icon="isMonitoring ? 'el-icon-video-pause' : 'el-icon-video-play'" 
              size="small" 
              @click="toggleMonitor">
              {{ isMonitoring ? '暂停' : '开始' }}监控
            </el-button>
            <el-button 
              type="info" 
              icon="el-icon-refresh" 
              size="small" 
              @click="refreshLogs">
              刷新
            </el-button>
            <el-button 
              type="warning" 
              icon="el-icon-delete" 
              size="small" 
              @click="clearLogs">
              清空
            </el-button>
          </el-button-group>
          
          <el-checkbox v-model="autoScroll" style="margin-left: 10px">自动滚动</el-checkbox>
          
          <el-select v-model="logLevel" placeholder="日志级别" size="small" style="width: 120px; margin-left: 10px">
            <el-option label="全部" value="ALL"/>
            <el-option label="DEBUG" value="DEBUG"/>
            <el-option label="INFO" value="INFO"/>
            <el-option label="WARN" value="WARN"/>
            <el-option label="ERROR" value="ERROR"/>
          </el-select>
        </div>
      </div>

      <div class="log-container" ref="logContainer">
        <div 
          v-for="(log, index) in filteredLogs" 
          :key="index" 
          :class="['log-line', getLogLevelClass(log)]">
          {{ log }}
        </div>
        <div v-if="filteredLogs.length === 0" class="empty-log">
          暂无日志数据
        </div>
      </div>

      <div class="log-footer">
        <span>总行数: {{ logs.length }}</span>
        <span style="margin-left: 20px">显示行数: {{ filteredLogs.length }}</span>
        <span style="margin-left: 20px" :class="isMonitoring ? 'status-running' : 'status-stopped'">
          {{ isMonitoring ? '● 监控中' : '○ 已暂停' }}
        </span>
      </div>
    </el-card>
  </div>
</template>

<script>
import request from '@/utils/request'

export default {
  name: 'LogMonitor',
  data() {
    return {
      logs: [],
      isMonitoring: false,
      autoScroll: true,
      logLevel: 'ALL',
      eventSource: null
    }
  },
  computed: {
    filteredLogs() {
      if (this.logLevel === 'ALL') {
        return this.logs
      }
      return this.logs.filter(log => log.includes(`[${this.logLevel}]`) || log.includes(this.logLevel))
    }
  },
  mounted() {
    this.loadRecentLogs()
  },
  beforeDestroy() {
    this.stopMonitor()
  },
  methods: {
    loadRecentLogs() {
      request({
        url: '/log-monitor/recent',
        method: 'get',
        params: { lines: 200 }
      }).then(res => {
        // 后端统一Result包装
        if (res.code === 200) {
          this.logs = res.data || []
        } else if (Array.isArray(res)) {
          // 兼容老接口直接返回数组
          this.logs = res
        } else {
          this.$message.error(res.message || '加载日志失败')
          this.logs = []
        }
        this.$nextTick(() => {
          this.scrollToBottom()
        })
      }).catch(err => {
        this.$message.error('加载日志失败: ' + err.message)
      })
    },
    toggleMonitor() {
      if (this.isMonitoring) {
        this.stopMonitor()
      } else {
        this.startMonitor()
      }
    },
    startMonitor() {
      if (this.eventSource) {
        return
      }

      this.isMonitoring = true
      this.logs = []
      
      // 使用SSE接收实时日志
      this.eventSource = new EventSource('/api/log-monitor/stream')
      
      this.eventSource.addEventListener('init', (event) => {
        console.log('日志监控已连接:', event.data)
      })
      
      this.eventSource.addEventListener('log', (event) => {
        this.logs.push(event.data)
        
        // 限制日志行数，避免内存溢出
        if (this.logs.length > 1000) {
          this.logs = this.logs.slice(-1000)
        }
        
        if (this.autoScroll) {
          this.$nextTick(() => {
            this.scrollToBottom()
          })
        }
      })
      
      this.eventSource.onerror = (error) => {
        console.error('SSE连接错误:', error)
        this.$message.error('日志监控连接断开，请重新开始')
        this.stopMonitor()
      }
    },
    stopMonitor() {
      if (this.eventSource) {
        this.eventSource.close()
        this.eventSource = null
      }
      this.isMonitoring = false
    },
    refreshLogs() {
      this.stopMonitor()
      this.loadRecentLogs()
    },
    clearLogs() {
      this.$confirm('确认清空所有日志？', '警告', {
        type: 'warning'
      }).then(() => {
        request({
          url: '/log-monitor/clear',
          method: 'delete'
        }).then(res => {
          this.$message.success('日志已清空')
          this.logs = []
        }).catch(err => {
          this.$message.error('清空日志失败: ' + err.message)
        })
      })
    },
    scrollToBottom() {
      const container = this.$refs.logContainer
      if (container) {
        container.scrollTop = container.scrollHeight
      }
    },
    getLogLevelClass(log) {
      if (log.includes('ERROR') || log.includes('[ERROR]')) {
        return 'log-error'
      } else if (log.includes('WARN') || log.includes('[WARN]')) {
        return 'log-warn'
      } else if (log.includes('INFO') || log.includes('[INFO]')) {
        return 'log-info'
      } else if (log.includes('DEBUG') || log.includes('[DEBUG]')) {
        return 'log-debug'
      }
      return ''
    }
  }
}
</script>

<style scoped>
.log-monitor {
  height: 100%;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-buttons {
  display: flex;
  align-items: center;
}

.log-container {
  height: calc(100vh - 250px);
  overflow-y: auto;
  background-color: #1e1e1e;
  color: #d4d4d4;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  padding: 10px;
  border-radius: 4px;
}

.log-line {
  line-height: 20px;
  padding: 2px 5px;
  white-space: pre-wrap;
  word-break: break-all;
}

.log-error {
  color: #f56c6c;
  background-color: rgba(245, 108, 108, 0.1);
}

.log-warn {
  color: #e6a23c;
  background-color: rgba(230, 162, 60, 0.1);
}

.log-info {
  color: #67c23a;
}

.log-debug {
  color: #909399;
}

.empty-log {
  text-align: center;
  color: #909399;
  padding: 50px 0;
}

.log-footer {
  margin-top: 10px;
  padding: 10px 0;
  border-top: 1px solid #ebeef5;
  font-size: 14px;
  color: #606266;
}

.status-running {
  color: #67c23a;
  font-weight: bold;
}

.status-stopped {
  color: #909399;
}
</style>

